﻿
#If Not (PocketPC OrElse Smartphone) Then

Imports System.IO
Imports System.Text

#Const STRINGWAY = False

#If STRINGWAY Then

Friend Class readeruntilLine
    <ThreadStatic()> Public Shared line As String = Nothing
End Class

Namespace readerHelper
    Public Module readerHelper
        Public Function readuntil(byVal reader As TextReader, ByVal until As String _
                                  , Optional ByVal containsUntilChars As Boolean = False _
                                  , Optional ByVal retrytimes As Int32 = 1024) As String
            If reader Is Nothing Then
                Return Nothing
            End If

            Const blocksize As Int32 = 1024
            Dim this As Int32 = 0
            Dim buff(blocksize - 1) As Char
            Dim untilIndex As Int32 = npos
            Dim untillen As Int64 = strlen(until)
            Do
                Try
                    this = reader.ReadBlock(buff, 0, blocksize)
                Catch ex As Exception
                    retrytimes -= 1
                    raiseError("cannot read characters from reader, " + ex.Message, errorHandle.errorType.system)
                End Try
                If this > 0 Then
                    readeruntilLine.line += New String(buff, 0, this)
                Else
                    retrytimes -= 1
                End If
                If Not isemptystring(readeruntilLine.line) Then
                    untilIndex = readeruntilLine.line.IndexOf( _
                                            until, max(Of Int32)(readeruntilLine.line.Length - this - untillen + 1, 0))
                End If
            Loop Until retrytimes = 0 OrElse untilIndex <> npos
            Dim rtn As String = Nothing
            If retrytimes > 0 Then
                If containsUntilChars Then
                    rtn = strleft(readeruntilLine.line, untilIndex + untillen)
                Else
                    rtn = strleft(readeruntilLine.line, untilIndex)
                End If
                readeruntilLine.line = strmid(readeruntilLine.line, untilIndex + untillen)
            End If
            Return rtn
        End Function
#Else

Friend Class readeruntilLine
    <ThreadStatic()> Public Shared line As StringBuilder = Nothing
End Class

Namespace readerHelper
    Public Module readerHelper
        Public Function readuntil(ByVal reader As TextReader, ByVal until As String _
                                  , Optional ByVal containsUntilChars As Boolean = False _
                                  , Optional ByVal retrytimes As Int32 = 1024) As String
            Const blocksize As Int32 = 1024

            If reader Is Nothing Then
                Return Nothing
            End If

            If readeruntilLine.line Is Nothing Then
                readeruntilLine.line = New StringBuilder(blocksize)
            End If

            Dim this As Int32 = 0
            Dim buff(blocksize - 1) As Char
            Dim untilIndex As Int32 = npos
            Dim untillen As Int64 = strlen(until)
            Do
                Try
                    this = reader.ReadBlock(buff, 0, blocksize)
                Catch ex As Exception
                    retrytimes -= 1
                    raiseError("cannot read characters from reader, " + ex.Message, errorHandle.errorType.system)
                End Try
                If this > 0 Then
                    readeruntilLine.line.Append(buff, 0, this)
                Else
                    retrytimes -= 1
                End If
                If Not isemptystring(readeruntilLine.line) Then
                    Dim i As Int64
                    For i = max(readeruntilLine.line.Length - this - untillen + 1, 0) To _
                            min(readeruntilLine.line.Length - untillen, -1)
                        If strcmp(readeruntilLine.line, i, untillen, until, 0, untillen, True) = 0 Then
                            untilIndex = i
                            Exit For
                        End If
                    Next
                End If
            Loop Until retrytimes = 0 OrElse untilIndex <> npos
            Dim rtn As String = Nothing
            If retrytimes > 0 Then
                If containsUntilChars Then
                    rtn = readeruntilLine.line.ToString(0, untilIndex + untillen)
                Else
                    rtn = readeruntilLine.line.ToString(0, untilIndex)
                End If
                readeruntilLine.line.Remove(0, untilIndex + untillen)
            End If
            Return rtn
        End Function

#End If

        Public Function readline(ByVal reader As IO.TextReader, Optional ByVal containsEOL As Boolean = False _
                                 , Optional ByVal retrytimes As Int32 = 1024) As String
            Return readuntil(reader, newline.incode(), containsEOL, retrytimes)
        End Function
    End Module
End Namespace

#End If